package schedule

import (
	"log"
	"os"
	"os/signal"
	"runtime"
	. "spider/common"
	"sync"
	"time"

	"spider/thirdparty/log4go.v1"
)

var logger = log4go.NewDefaultLogger(log4go.DEBUG)

type ISchedule interface {
	Schedule()
}
type DefaultSchedule struct {
	count   int
	spider  *Spider
	crawled chan bool
	quit    chan bool
	locker  sync.Mutex
}

func NewDefaultSchedule(spider *Spider) *DefaultSchedule {
	return &DefaultSchedule{
		spider:  spider,
		crawled: make(chan bool, 100),
		quit:    make(chan bool),
	}
}
func (self *DefaultSchedule) WorkReport() {
	go func() {
		ticker := time.Tick(time.Second * 2)
	L:
		for {
			select {
			case <-ticker:
				logger.Info("report:%d goroutines work", runtime.NumGoroutine())
				logger.Info("report:%d requests complete.\n", self.count)
			case <-self.quit:
				break L
			}
		}

	}()
}
func (self *DefaultSchedule) Schedule() {
	defer func() {
		log.Println(string(self.spider.Context.Stats.Report()))
	}()
	self.WorkReport()
	self.spider.Context.DownloaderWork()
	self.spider.Context.SpiderWork()
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
L:
	for {
		select {
		case <-c:
			self.spider.Context.SpiderClose <- true
		case result := <-self.spider.Context.WorkResultPipe:
			self.count += 1
			self.spider.Context.Stats.Crawled += 1
			if result.Result {
				self.spider.Context.Stats.Successed += 1
			} else {
				self.spider.Context.Stats.Failed += 1
			}
		case <-self.crawled:
			self.count += 1
			self.spider.Context.Stats.Successed += 1
		case <-self.spider.Context.SpiderClose:
			log.Println("spider has been closed")
			break L
		case <-time.After(time.Second * 30):
			self.quit <- true
			break L
		}
	}

}
